<template>
  <div class="main-box">
    <TreeFilter title="表" :data="listTableInfoData" :multiple="false" :default-value="tableInfoId" @change="changeTreeFilter" />
    <el-tabs type="border-card" class="table-box demo-tabs" tab-position="top" v-model="tabVal">
      <el-tab-pane name="all">
        <template #label>
          <span class="custom-tabs-label">
            <!--            <el-icon><calendar /></el-icon>-->
            <span>全部</span>
          </span>
        </template>
      </el-tab-pane>

      <el-tab-pane v-for="item in ColumnDimensionType" :key="item.value" :label="item.label" :name="item.value" />
      <el-tab-pane label="预览" name="preview" :disabled="true">
        <template #label>
          <el-dropdown>
            <span class="el-dropdown-link"> 预览 </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="tabClick('select')"> 查询页面</el-dropdown-item>
                <el-dropdown-item @click="tabClick('add')"> 新增表单</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
      </el-tab-pane>

      <el-scrollbar height="100%" v-show="tabVal != 'preview'">
        <ProTable
          ref="proTable"
          highlight-current-row
          :columns="columns"
          :data="filterTableColumns"
          :tool-button="[]"
          :pagination="false"
          :init-param="tableInfoId"
          @darg-sort="sortTable"
        >
          <template #defaultValue="scope">
            {{
              scope.row.defaultValue
                ? formatTableColumn[scope.row.columnCode]
                  ? formatTableColumn[scope.row.columnCode][scope.row.defaultValue]
                  : scope.row.defaultValue
                : ""
            }}
          </template>

          <template #empty="scope">
            <el-button type="primary" circle size="large" :icon="Plus" @click="add(scope)" />
          </template>
          <template #operation="scope">
            <el-button type="primary" circle size="small" :icon="View" @click="add(scope, true)" />
            <el-button type="primary" circle size="small" :icon="CopyDocument" @click="add(scope, false)" />
            <el-button type="primary" circle size="small" :icon="Edit" @click="update(scope)" />
            <el-button type="danger" circle size="small" :icon="Delete" @click="deleteTableColumn(scope)" />
          </template>
        </ProTable>
      </el-scrollbar>
    </el-tabs>
    <AddDataDialog :columns="tableColumns" ref="addDataDialog" :preview="true" title="预览添加表单"></AddDataDialog>

    <AddColumn ref="addColumnRef" @submit-success="reloadData" />
  </div>
</template>
<script setup lang="tsx" name="tableColumn">
import { computed, onMounted, reactive, ref, watch } from "vue";
import { ElMessage } from "element-plus";

import { useHandleData } from "@/hooks/useHandleData";
import {
  ColumnDimensionType,
  ColumnDimensionTypes,
  ColumnOptionsType,
  ColumnType,
  ColumnTypeEnum,
  DateRange,
  DimensionExtraEnum,
  DimensionTypeEnum
} from "@/utils/dict";
import ProTable from "@/components/ProTable/index.vue";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { ColumnProps, ProTableInstance, RenderScope } from "@/components/ProTable/interface";
import { CopyDocument, Delete, Edit, Plus, View } from "@element-plus/icons-vue";
import { useRoute, useRouter } from "vue-router";
import { simpleUserTableDataController, tableColumnController, tableInfoController } from "@/api/modules/dwh";
import { API } from "@/api/modules/dwh/typings";
import { clearObject } from "@/utils";
import { isArray } from "@/utils/is";
import AddDataDialog from "@/views/dwh/tableColumn/addDataDialog.vue";
import AddColumn from "@/views/dwh/tableColumn/components/addColumn.vue";
import { getColumnOptionsType } from "@/utils/TableColumnUtil";

// ProTable 实例
const proTable = ref<ProTableInstance>();

const tabVal = ref<string>("all");

let route = useRoute();
let tableInfoId = ref<string>();
const router = useRouter();
const addDataDialog = ref<typeof AddDataDialog>();

const tabClick = (value: any) => {
  if (value == "select") {
    router.push(`/dwh/tableColumn/preview/${tableInfoId.value}`);
  } else if (value == "add") {
    addDataDialog.value?.show();
  }
};

let tableColumns = ref<Array<API.TableColumnVo>>([]);

const filterTableColumns = computed(() => {
  if (!tableInfoId.value) {
    return [];
  }
  let data = tableColumns.value.filter(data => {
    return (
      (tabVal.value == "all" ? true : data.dimensionType?.includes(tabVal.value)) &&
      (!search.val ||
        !data.id ||
        data.columnCode?.toLowerCase().includes(search.val.toLowerCase()) ||
        data.columnName?.toLowerCase().includes(search.val.toLowerCase()))
    );
  });
  return data;
});
const formatTableColumn = reactive<{ [key: string]: any }>({});
const listTableColumns = async (id: string | undefined) => {
  let result = await tableColumnController.listUsingGET({ param: Number(id) });
  result.data.forEach(data => {
    if (data.dimensionType == DimensionTypeEnum.agg) {
      data.columnCode = data.columnCode.split("@")[1];
    }
    data.dimensionType = [data.dimensionType, data.dimensionExtra];
  });
  tableColumns.value = result.data;

  clearObject(formatTableColumn);
  Object.keys(formatTableColumn).forEach(k => delete formatTableColumn[k]);
  tableColumns.value.forEach(column => {
    if (column.defaultValue) {
      let columnOptionsType = getColumnOptionsType(column.columnOptions);
      if (column.columnType == ColumnTypeEnum.date) {
        formatTableColumn[column.columnCode] = DateRange.reduce((accumulator: { [key: string]: any }, currentValue) => {
          // 设置初始值为空字符串或其他默认值
          accumulator[currentValue.value] = currentValue.label;
          return accumulator;
        }, {});
      } else if (columnOptionsType == ColumnOptionsType.custom) {
        formatTableColumn[column.columnCode] = column
          .columnOptions!.split(",")
          .reduce((accumulator: { [key: string]: any }, currentValue: string) => {
            // 设置初始值为空字符串或其他默认值
            let options = currentValue.split(":");
            accumulator[options[0]] = options[1];
            return accumulator;
          }, {});
      } else if (columnOptionsType == ColumnOptionsType.link_table) {
        let table = JSON.parse(column.columnOptions!);
        simpleUserTableDataController
          .pageUserTableDataUsingPOST({
            page: { pageIndex: 1, pageSize: 100 },
            query: { tableInfoId: Number(table.tableInfoId) }
          })
          .then(res => {
            formatTableColumn[column.columnCode] = res.data.reduce(
              (accumulator: { [key: string]: any }, item: API.PageUserTableDataVo) => {
                // 设置初始值为空字符串或其他默认值
                let valueCode = item.tableData?.find((tableData: API.UserTableDataVo) => tableData.columnCode == table.valueCode)
                  ?.value;
                let valueLabel = item.tableData?.find(
                  (tableData: API.UserTableDataVo) => tableData.columnCode == table.valueLabel
                )?.value;
                accumulator[valueCode] = valueLabel;
                return accumulator;
              },
              {}
            );
          });
      }
    }
  });
};

const reloadData = async () => {
  await listTableColumns(tableInfoId.value);
};

const listTableInfoData = ref<{}[]>([]);

onMounted(() => {
  listTableInfo();
});

const listTableInfo = async () => {
  let tableInfos = await tableInfoController.pageUsingPOST({ page: { pageIndex: 1, pageSize: 1000 }, query: {} });
  let result: any = {};
  if (tableInfos?.data) {
    for (const tableInfo of tableInfos.data) {
      if (tableInfo.dataSource) {
        result[tableInfo.dataSource] ?? (result[tableInfo.dataSource] = []);
        result[tableInfo.dataSource].push(tableInfo);
      }
    }
  }
  if (route.params.id != ":id") {
    tableInfoId.value = isArray(route.params.id) ? route.params.id[0] : route.params.id;
  }
  for (const dataSource in result) {
    let children: Array<{}> = [];
    result[dataSource].forEach(tableInfo => {
      children.push({ id: tableInfo.id, label: tableInfo.name, subTitle: tableInfo.tableName });
      if (!tableInfoId.value) {
        tableInfoId.value = String(tableInfo.id);
      }
    });

    listTableInfoData.value.push({
      id: dataSource,
      label: dataSource,
      children: children
    });
  }
};

watch([tableInfoId], newVal => {
  listTableColumns(newVal[0]);
});

const addColumnRef = ref<InstanceType<typeof AddColumn> | null>(null);

const add = async (scope: RenderScope<API.TableColumnVo>, preview?: boolean) => {
  if (scope.row) {
    let newRow: API.TableColumnVo = Object.assign({}, scope.row);
    delete newRow.id;
    addColumnRef.value?.show(newRow, preview);
  } else {
    let firstRow = {
      columnCode: "",
      columnName: "主键",
      columnOptions: "",
      columnType: ColumnTypeEnum.string,
      tableInfoId: tableInfoId,
      orderNo: 1,
      dimensionType: [DimensionTypeEnum.dimension, DimensionExtraEnum.dimension_primary_key]
    };
    addColumnRef.value?.show(firstRow, preview);
  }
};
const srcFilterTableColumns = ref();
watch(filterTableColumns, newVal => {
  srcFilterTableColumns.value = [...newVal];
});

// 表格拖拽排序
const sortTable = async ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
  if (newIndex === oldIndex) {
    return;
  }
  let srcTableColumnVo = srcFilterTableColumns.value[oldIndex!];
  let targetTableColumnVo = srcFilterTableColumns.value[newIndex!];

  await tableColumnController.sortTableColumnUsingPOST({
    id: srcTableColumnVo.id as number,
    orderNo: targetTableColumnVo.orderNo!
  });
  reloadData();
  ElMessage.success("修改列表排序成功");
};
// 更新
const update = async (scope: RenderScope<API.TableColumnVo>) => {
  addColumnRef.value?.show(scope.row, false);
};

// 更新
const deleteTableColumn = async (scope: RenderScope<API.TableColumnVo>) => {
  let row = scope.row;
  await useHandleData(
    tableColumnController.deleteUsingGET,
    { param: row.id },
    `删除 ${row.columnCode}:${row.columnName} 所选字段`
  );
  listTableColumns(tableInfoId.value);
};

const search = reactive({ val: "" });

// 表格配置项
const columns = reactive<ColumnProps<API.TableColumnVo>[]>([
  { type: "sort", label: "Sort", width: 80 },
  {
    prop: "columnCode",
    label: "code"
  },
  {
    prop: "columnName",
    label: "名称"
  },
  {
    prop: "columnType",
    label: "数据类型",
    enum: ColumnType
  },
  {
    prop: "dimensionType",
    label: "类型",
    render: scope => {
      let columnDimensionType = ColumnDimensionTypes[scope.row.columnType!].find(
        column => column.value == (scope.row.dimensionType[0] ?? "")
      );
      let label = columnDimensionType?.label;
      if (scope.row.dimensionExtra) {
        label += "-" + columnDimensionType?.children?.find(column => column.value == scope.row.dimensionType[1])?.label;
      }
      return label;
    }
  },
  {
    prop: "columnOptions",
    label: "枚举值"
  },
  {
    prop: "defaultValue",
    label: "默认值"
  },
  {
    prop: "operation",
    label: "操作",
    fixed: "right",
    width: 170,
    headerRender: scope => {
      return <el-input v-model={search.val} size="default" placeholder="搜索" />;
    }
  }
]);

// 默认 treeFilter 参数
const changeTreeFilter = (val: string) => {
  tableInfoId.value = val;
};
</script>
<style scoped>
.demo-tabs > .el-tabs__content {
  padding: 32px;
  font-size: 32px;
  font-weight: 600;
  color: #6b778c;
}

.demo-tabs .custom-tabs-label .el-icon {
  vertical-align: middle;
}

.demo-tabs .custom-tabs-label span {
  margin-left: 4px;
  vertical-align: middle;
}
</style>
